#import "TCCIAP.h"
#import <StoreKit/StoreKit.h>
#import "TCCIAPModel.h"
//#import "TCCDB.h"
NSString * const TCCIAPNotification = @"TCCIAPNotification";
NSString * const talbeName = @"stu";
@interface TCCIAP()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
@property (nonatomic, copy) NSSet <NSString *> * commodityIDs;
@property (nonatomic, strong) TCCIAPModel *orderModel;
@property (nonatomic, strong) CCDB *ccdb;
@property (nonatomic, strong) SKProductsRequest *request;
@end
@implementation TCCIAP
static TCCIAP*_tccIAPManager;
static dispatch_once_t _tccIAPManagerOnceToken;
+ (instancetype)IAPManager
{
    if (!_tccIAPManager)
    {
        dispatch_once(&_tccIAPManagerOnceToken,^{
            _tccIAPManager = [[TCCIAP alloc] init];
        });
    }
    return  _tccIAPManager;
}
- (CCDB *)ccdb
{
    if (!_ccdb)
    {
        _ccdb = [CCDB db];
        [_ccdb openDM:@"Receipt"];
        [_ccdb createTable:talbeName withOptions:@[@"zfID", @"goodsID", @"receipt", @"isDid"]];
    }
    return _ccdb;
}
- (SKProductsRequest *)request
{
    if(!_request)
    {
        _request = [[SKProductsRequest alloc] initWithProductIdentifiers:self.commodityIDs];
        _request.delegate = self;
    }
    return _request;
}
+ (BOOL)yjd_isDoing
{
    TCCIAP *_zf = [TCCIAP IAPManager];
    return (_zf.orderModel)?YES:NO;
}
+ (void)yjd_zf:(NSString *)passString goodsID:(NSString *)goodsID;
{
    if ([SKPaymentQueue canMakePayments])
    {
        DeLog(@"yes");
        TCCIAP *_zf = [TCCIAP IAPManager];
        if (_zf.orderModel == nil)
        {
            _zf.orderModel = nil;
            _zf.request = nil;
            _zf.orderModel = [[TCCIAPModel alloc] init];
            _zf.orderModel.zfID = passString;
            _zf.orderModel.goodsID = goodsID;
            _zf.commodityIDs = [NSSet setWithObjects:goodsID, nil];
            [_zf.request start];
            [self postNotify:TCCIAPStatusWillRequest info:nil];
        }
        else
        {
            [self postNotify:TCCIAPStatusDoingRequest info:nil];
        }
    }
    else
    {
        [self postNotify:TCCIAPStatusNonSupportRequest info:nil];
    }
}
#pragma mark - SKProductsRequestDelegate <SKRequestDelegate> method
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *products = response.products;
    if([products count] == 0)
    {
        DeLog(@"nothing");
        self.orderModel = nil;
        [TCCIAP postNotify:TCCIAPStatusNothingRequest info:nil];
        return;
    }
    for (SKProduct *pro in products)
    {
        SKProduct *requestProduct = nil;
        self.orderModel.goodsID = (pro.productIdentifier)?pro.productIdentifier:self.orderModel.goodsID;
        DeLog(@"1%@", [pro priceLocale]);
        DeLog(@"2%@", [pro localizedTitle]);
        DeLog(@"3%@", [pro localizedDescription]);
        DeLog(@"4%@", [pro price]);
        DeLog(@"5%@", [pro productIdentifier]);
        if([self.commodityIDs containsObject:pro.productIdentifier])
        {
            TCCIAPModel *model = [[TCCIAPModel alloc] init];
            model.zfID = self.orderModel.zfID;
            model.goodsID = self.orderModel.goodsID;
            model.isDid = @"0";
            //            [_ccdb insert:model];
            [_ccdb insert:talbeName withDict:@{@"zfID":model.zfID, @"goodsID":model.goodsID, @"isDid":@"0"}];
            requestProduct = pro;
            SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:requestProduct];
            payment.applicationUsername = self.orderModel.zfID;
            [[SKPaymentQueue defaultQueue] addPayment:payment];
        }
    }
}
#pragma mark - SKRequestDelegate -- Method
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
    self.orderModel = nil;
    [TCCIAP postNotify:TCCIAPStatusFailRequest info:error.localizedDescription];
    DeLog(@"请求失败%@",error.localizedDescription);
}
- (void)requestDidFinish:(SKRequest *)request
{
    DeLog(@"信息反馈结束");
}
#pragma mark - SKPaymentTransactionObserver method
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
{
    for(SKPaymentTransaction *tran in transaction){
        switch (tran.transactionState) {
            case SKPaymentTransactionStatePurchasing://正在购买
                DeLog(@"正在购买");
                break;
            case SKPaymentTransactionStatePurchased://已经购买
                DeLog(@"交易完成");
                if ([self.orderModel.zfID length] > 1 && [self.orderModel.zfID isEqualToString:tran.payment.applicationUsername])
                {
                    [self updateDB];
                    [queue finishTransaction:tran];
                }
                [self yjd_completeTransaction:tran];
                break;
            case SKPaymentTransactionStateRestored://恢复购买
                DeLog(@"恢复购买");
                break;
            case SKPaymentTransactionStateFailed://购买失败
                DeLog(@"交易失败");
                self.orderModel = nil;
                [queue finishTransaction:tran];
                [TCCIAP postNotify:TCCIAPStatusCancelRequest info:tran.error.localizedDescription];
                break;
            case SKPaymentTransactionStateDeferred:
                DeLog(@"事务在队列中，但它的最终状态正在等待外部操作");
                break;
            default:
                break;
        }
    }
}
- (void)yjd_completeTransaction:(SKPaymentTransaction *)transaction
{
    NSData *receiptData = nil;
#ifdef iOS7Later
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    receiptData = [NSData dataWithContentsOfURL:receiptURL];
#else
    NSString * str = [[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
    receiptData = [NSData dataWithBytes:[str UTF8String] length:[str length]];
#endif
    NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    NSString *environment = ([[receiptURL absoluteString] containsString:@"sandbox"])?@"Sandbox":@"Appstore";
    [TCCIAP postNotify:TCCIAPStatusSuccessRequest info:nil];
    [self yjd_submitToSDKServer:encodeStr environment:environment transaction:transaction];
}
- (void)submitToAppleServer:(NSString *)string withEnvironment:(NSString *)environment
{
}
- (void)yjd_submitToSDKServer:(NSString *)string environment:(NSString *)environment transaction:(SKPaymentTransaction *)transaction
{
    if([self.orderModel.zfID length] < 1 || ![self.orderModel.zfID isEqualToString:transaction.payment.applicationUsername])
    {
        NSString *goodsID = transaction.payment.productIdentifier;
        __block NSString *zfID = transaction.payment.applicationUsername;
        if ([zfID length] < 1)
        {
            //            NSMutableArray *arr = [_ccdb select:@"0"];
            [_ccdb select:talbeName withOptions:nil conditionsDict:@{@"isDid":@"0"} complete:^(NSMutableArray * _Nonnull array) {
                for (NSDictionary *dict in array)
                {
                    if ([[dict valueForKey:@"goodsID"] isEqualToString:goodsID])
                    {
                        zfID = [dict valueForKey:@"zfID"];//注意，这里block返回时在异步返回，可能会有延迟，导致下一步验证的时候zfID还是可能会出现nil
                    }
                }
                [self getParaWithzfID:zfID receipt:string environment:environment block:^{
                    [self.ccdb delet:talbeName withDict:@{@"zfID":zfID}];
                    //                [self.ccdb deleteWithModel:model];
                    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                }];
            }];
        }
        else
        {
            [self getParaWithzfID:zfID receipt:string environment:environment block:^{
                [self.ccdb delet:talbeName withDict:@{@"zfID":zfID}];
                //                [self.ccdb deleteWithModel:model];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            }];
        }
    }
    else
    {
        TCCIAPModel *model = [[TCCIAPModel alloc] init];
        model.zfID = self.orderModel.zfID;
        model.goodsID = self.orderModel.goodsID;
        model.receipt = string;
        model.enviroment = environment;
        model.isDid = @"1";
        if (model.zfID && model.receipt)
        {
            [_ccdb update:talbeName withDict:@{@"goodsID":model.goodsID, @"receipt":model.receipt, @"isDid":@"1"} conditionsDict:@{@"zfID":model.zfID}];
        }
        //        [_ccdb update:model];
        [self getParaWithzfID:self.orderModel.zfID receipt:string environment:environment block:^{
            [self.ccdb delet:talbeName withDict:@{@"zfID":model.zfID}];
        }];
    }
}
- (void)updateDB
{
    if (self.orderModel.zfID && self.orderModel.goodsID)
    {
        TCCIAPModel *model = [[TCCIAPModel alloc] init];
        model.zfID = self.orderModel.zfID;
        model.goodsID = self.orderModel.goodsID;
        model.isDid = @"1";
        [_ccdb update:talbeName withDict:@{@"goodsID":model.goodsID, @"receipt":model.receipt?model.receipt:@"", @"isDid":@"1"} conditionsDict:@{@"zfID":model.zfID}];
    }
}
-(NSString * )yjd_environmentForReceipt:(NSString * )str
{
    str = [str stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];
    str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    str = [str stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
    str = [str stringByReplacingOccurrencesOfString:@"\"" withString:@""];
    NSArray * arr = [str componentsSeparatedByString:@";"];
    NSString * environment=arr[2];
    return environment;
}
+ (void)postNotify:(int)status info:(NSString *)info
{
    info = (info)?info:@"";
    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:TCCIAPNotification object:nil userInfo:@{@"status":[NSString stringWithFormat:@"%d",status],@"info":info}];
    });
}
+ (void)yjd_checkQueueAndDB
{
    TCCIAP * _tccIAPManager = [TCCIAP IAPManager];
    [_tccIAPManager deleteDBoutOfDate];
    
    [_tccIAPManager.ccdb select:talbeName withOptions:nil conditionsDict:@{@"isDid":@"1"} complete:^(NSMutableArray * _Nonnull array) {
        for (NSDictionary *dict in array)
        {
            if ([[dict valueForKey:@"receipt"] length] > 10)
            {
                [TCCIAP getParaWithzfID:[dict valueForKey:@"zfID"] receipt:[dict valueForKey:@"receipt"] environment:[dict valueForKey:@"enviroment"] block:^{
                    [_tccIAPManager.ccdb delet:talbeName withDict:@{@"zfID":[dict valueForKey:@"zfID"]}];
                }];
            }
        }
        [[SKPaymentQueue defaultQueue] addTransactionObserver:_tccIAPManager];
    }];
}
- (void)deleteDBoutOfDate
{
    NSString *date = [NSString stringWithFormat:@"%f",[[NSDate date] timeIntervalSince1970]];
    int time_now = [[date componentsSeparatedByString:@"."][0] intValue];
    [_tccIAPManager.ccdb select:talbeName withOptions:nil conditionsDict:@{@"isDid":@"0"} complete:^(NSMutableArray * _Nonnull array) {
        for (NSDictionary *dict in array)
        {
            int time = [[dict valueForKey:@"time"] intValue];
            if (time_now - time > 259200)
            {
                [_tccIAPManager.ccdb delet:talbeName withDict:@{@"zfID":[dict valueForKey:@"zfID"]}];
            }
        }
    }];
}
- (void)getParaWithzfID:(NSString *)zfID receipt:(NSString*)receipt environment:(NSString *)environment block:(void (^) (void))block
{
    self.orderModel = nil;
    [TCCIAP getParaWithzfID:zfID receipt:receipt environment:environment block:block];
}
+ (void)getParaWithzfID:(NSString *)zfID receipt:(NSString*)receipt environment:(NSString *)environment block:(void (^) (void))block
{
    NSMutableDictionary *para = [NSMutableDictionary dictionary];
    [para setValue:[XOWMPlatform platform].appID forKey:@"appid"];
    [para setValue:zfID forKey:@"payid"];
    [para setValue:receipt forKey:@"receipt"];
    [para setValue:environment forKey:@"environment"];
    NSString *transdata = [para yjd_json];
    transdata = [transdata stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"];
    NSString *signTransdata = [transdata yjd_sign];
    NSMutableDictionary *newPara = [NSMutableDictionary dictionary];
    [newPara setValue:transdata forKey:@"transdata"];
    [newPara setValue:@"RSA" forKey:@"signtype"];
    [newPara setValue:signTransdata forKey:@"sign"];
    [XOWMHttps post:VERIFY_ZF_API parameters:newPara complete:^(id data) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSString *sign = [dict valueForKey:@"sign"];
        NSString *transString = [dict valueForKey:@"transdata"];
        BOOL isSuccess = [transString yjd_verifySign:sign];
        int code = -1;
        code = [[[transString yjd_dict] valueForKey:@"code"] intValue];
        if (isSuccess && code == 100)
        {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                if (block) block();
            });
        }
    } error:^(NSError *error) {
        [TCCIAP IAPManager].orderModel = nil;
        DeLog(@"sdk    验证失败 error %@",error);
    }];
}

@end
